package com.hqyj.springbootdemo01.shiro;

import com.hqyj.springbootdemo01.common.config.JwtFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author sdx2009
 * @package com.hqyj.springbootdemo01.shiro
 * @date 2022/8/30 9:05
 */

@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());

//        关闭shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
        evaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(evaluator);
        securityManager.setSubjectDAO(subjectDAO);

        return securityManager;
    }

    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());

        factoryBean.setLoginUrl("/api/user/login");

        Map<String, Filter> map = new HashMap<>();
        map.put("jwt", new JwtFilter());
        factoryBean.setFilters(map);

        Map<String, String> filterMap = new HashMap<>();
        filterMap.put("/**", "jwt");
        filterMap.put("/api/user/login", "anon");
        filterMap.put("/api/redis/*", "anon");
        filterMap.put("/api/user/401", "anon");
//        authc会拦截所有的请求，包括OPTIONS请求，这里把它注释掉
//        filterMap.put("/**", "authc");

        factoryBean.setFilterChainDefinitionMap(filterMap);

        return factoryBean;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
//        扫描advisor，开启注解
        proxyCreator.setProxyTargetClass(true);
//        开启advisor的前缀扫描
        proxyCreator.setUsePrefix(true);
        return proxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager());
        return advisor;
    }
}
